feat(appkit): split the agents plugin into focused modules (#532) - #547
Conversation
9831cec to
a8f7cba
Compare
atilafassina
left a comment
There was a problem hiding this comment.
it looks like this PR adds new behavior. I think you should consider changing from refactor to feat
a8f7cba to
be33197
Compare
📦 Bundle size reportCompared against
|
| dist | raw | gzip |
|---|---|---|
| JS (runtime) | 1.0 MB (+6.3 KB) | 376 KB (+4.8 KB) |
| Type declarations | 385 KB (-3.2 KB) | 136 KB (-1.1 KB) |
| Source maps | 2.1 MB (+10 KB) | 704 KB (+7.7 KB) |
| Other | 11 KB | 3.7 KB |
| Total | 3.5 MB (+13 KB) | 1.2 MB (+11 KB) |
Per-entry composition (own code — deps external (as shipped))
| Entry | Initial (gz) | Lazy (gz) | Total (gz) | node_modules (min) | Own code (min) |
|---|---|---|---|---|---|
. |
95 KB | 2.5 KB | 97 KB | external | 311 KB |
./beta |
75 KB (+344 B) | 456 B | 75 KB (+344 B) | external | 225 KB (+956 B) |
./testing |
17 KB | 0 B | 17 KB | external | 50 KB |
./tsdown |
520 B | 0 B | 520 B | external | 813 B |
./type-generator |
22 KB | 0 B | 22 KB | external | 65 KB |
Chunks:
| Entry | Chunk | Load | Size (gz) |
|---|---|---|---|
. |
index.js |
initial | 91 KB |
. |
utils.js |
initial | 4.0 KB |
. |
remote-tunnel-manager.js |
lazy | 2.5 KB |
./beta |
beta.js |
initial | 59 KB |
./beta |
stream-manager.js |
initial | 5.8 KB |
./beta |
wide-event-emitter.js |
initial | 3.2 KB |
./beta |
databricks.js |
initial | 3.0 KB |
./beta |
configuration.js |
initial | 2.1 KB |
./beta |
service-context.js |
initial | 1.3 KB |
./beta |
client.js |
initial | 434 B |
./beta |
client-options.js |
initial | 219 B |
./beta |
supervisor-api.js |
lazy | 192 B |
./beta |
databricks.js |
lazy | 141 B |
./beta |
index.js |
lazy | 123 B |
./testing |
index.js |
initial | 17 KB |
./tsdown |
index.js |
initial | 520 B |
./type-generator |
index.js |
initial | 22 KB |
@databricks/appkit-ui
npm tarball (packed): 350 KB — gzipped download (dist + bin; excludes release-only docs/NOTICE).
| dist | raw | gzip |
|---|---|---|
| JS (runtime) | 395 KB | 132 KB |
| Type declarations | 229 KB | 84 KB |
| Source maps | 766 KB | 253 KB |
| CSS | 16 KB | 3.2 KB |
| Total | 1.4 MB | 473 KB |
Per-entry composition (consumer bundle — deps bundled, peerDeps external)
| Entry | Initial (gz) | Lazy (gz) | Total (gz) | node_modules (min) | Own code (min) |
|---|---|---|---|---|---|
./js |
5.3 KB | 49 KB | 55 KB | 208 KB | 14 KB |
./js/beta |
20 B | 0 B | 20 B | 0 B | 0 B |
./react |
432 KB | 49 KB | 481 KB | 1.3 MB | 177 KB |
./react/beta |
1.0 KB | 0 B | 1.0 KB | 0 B | 1.9 KB |
Chunks:
| Entry | Chunk | Load | Size (gz) |
|---|---|---|---|
./js |
index.js |
initial | 5.2 KB |
./js |
chunk |
initial | 120 B |
./js |
apache-arrow |
lazy | 49 KB |
./js/beta |
beta.js |
initial | 20 B |
./react |
index.js |
initial | 430 KB |
./react |
tslib |
initial | 2.1 KB |
./react |
apache-arrow |
lazy | 49 KB |
./react/beta |
beta.js |
initial | 1.0 KB |
🤖 AppKit PR bot🔬 Run evalsStart an eval for this PR from the evals-monitor app: Go to Evals Monitor → 📦 Try this PR's app templateScaffolds a new app from this PR's SDK build. Run it in any folder (requires the GitHub CLI — gh run download 33384298640 -R databricks/appkit -n appkit-template-0.68.0-pr.ae5d702-refactor-agents-plugin-547 -D appkit-pr-547 \
&& unzip -o "appkit-pr-547/appkit-template-0.68.0-pr.ae5d702-refactor-agents-plugin-547.zip" -d "appkit-pr-547" \
&& databricks apps init --template "appkit-pr-547"The template pins |
…ules Step 1 of splitting the ~2.5k-line agents plugin. Moves module-scope pure functions/constants out of agents.ts verbatim (behavior-preserving): - approval.ts requiresApproval - prompt.ts composePromptForAgent - builtin-tools.ts LOAD_SKILL_TOOL_DEF, READ_SKILL_FILE_TOOL_DEF - adapter-extensions.ts buildAdapterExtensions, supervisorToolDescription, warnOnCapabilityMismatch agents.ts: 2512 -> 2331 lines. typecheck + 394 agent tests green. Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
…ader Step 2 of splitting the agents plugin. Moves skill discovery, per-agent catalog resolution, and the load_skill/read_skill_file dispatch into skill-loader.ts as free functions; the class keeps thin delegators (call sites unchanged) and skillWorkspaceClient() as the OBO credential seam. agents.ts: 2331 -> 2152 lines. typecheck + 394 agent tests green. Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
Step 3 of splitting the agents plugin. Moves the decoupled boot-time assembly helpers into registry.ts: loadCodeAgents, hasCodeAgentSources (now internal), resolveDefaultAgent, and the AgentSource type. buildAgentRegistry stays as the orchestrator that wires them. Also merges a duplicate import in skill-loader.ts. agents.ts: 2152 -> 2088 lines. typecheck + 394 agent tests green. Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
…tch.ts Step 4 (final) of splitting the agents plugin. Moves dispatchToolCall + runSubAgent — the tool-call budget, approval gate, and sub-agent recursion — into tool-dispatch.ts as free functions over RunState + a ToolDispatchDeps object. The plugin builds deps via toolDispatchDeps(); the two executeTool closures call the free function. RunState moves with them. Tests updated to invoke the free functions (deps built from the plugin's own builder). agents.ts: 2088 -> 1839 lines (2512 -> 1839 across all four steps). typecheck + 394 agent tests green. Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
…g.ts Moves resolvedApprovalPolicy / resolvedLimits defaulting into pure functions over AgentsPluginConfig. The getters keep the approval-policy memo cache and delegate. Config-only interface; both now unit-testable in isolation. agents.ts: 1839 -> 1812 lines. typecheck + agent tests green. Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
Moves the active-stream map + per-user counter (the O(1) concurrency-limit check) into a StreamRegistry class. The plugin holds one instance and keeps trackStream/untrackStream/countUserStreams as delegators; cancel/approve read via streams.get(). Tests inject via trackStream and assert via the registry. agents.ts: 1812 -> 1784 lines. typecheck + 394 agent tests green. Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
The previous commit named it StreamRegistry, colliding with the existing SSE-layer StreamRegistry in src/stream/ (connection/event-buffer tracking used by StreamManager). They're different concepts; renamed the agents-plugin one to ActiveStreamTracker (tracks active streams + per-user counts for the O(1) concurrency limit) to avoid the name clash. Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
…ing) The prior commit's git add hit the already-deleted stream-registry.ts path, aborted, and recorded only the deletion — leaving the pushed tip non-compiling (agents.ts imported the removed file; active-stream-tracker.ts was uncommitted). This adds the new module and the agents.ts import/usage so the tree builds. Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
0a37f9f to
49c18cb
Compare
Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
Summary
Behavior-preserving refactor of the ~2,500-line
agents.tsgod-file into focused modules. Stacked on #543 (it only touchesagents.ts, which #543 owns) — independent of #544.No behavior changes: every commit keeps
pnpm --filter=@databricks/appkit typecheckand the agent test suite (394 tests) green.agents.ts: 2,512 → 1,784 lines (−728, ~29%). The plugin is now an orchestrator (registry wiring + route handlers + SSE plumbing) delegating cohesive concerns to focused sibling modules.What moved
approval.ts,prompt.ts,builtin-tools.ts,adapter-extensions.ts.skill-loader.ts(discovery, catalog resolution,load_skill/read_skill_file).registry.ts(loadCodeAgents,hasCodeAgentSources,resolveDefaultAgent,AgentSource).tool-dispatch.ts(RunState+dispatchToolCall+runSubAgent) as free functions over aToolDispatchDepsobject.resolve-config.ts(resolveApprovalPolicy/resolveLimitspure fns; getters keep the memo cache).ActiveStreamTracker(active-stream map + per-user O(1) concurrency counter). Named to avoid clashing with the unrelated SSE-layerStreamRegistryinsrc/stream/.Notes
skillWorkspaceClient()stays as the OBO credential seam.buildToolIndex(owns the mutablemcpClientlifecycle) and the HTTP handlers (thePluginroute contract) — both need 5-8 pieces of plugin state, so extraction would widen interfaces more than it'd clarify (fails the deep-module test). The remaining ~1,784 lines are the plugin genuinely being a plugin.StreamRegistry: that one is a global, transport-level store (event replay buffers, global cap) with no per-user dimension; this one counts streams per user formaxConcurrentStreamsPerUser+ ownership checks.dispatch-tool-call,dos-limits,approval-route).Merge order
Stacked on #543; auto-retargets to
mainonce #543 merges. Merge after #543.